/**
 * 新建统计项目弹出框
 */
import React from 'react';
import { WeaFormItem, WeaInput, WeaTextarea, WeaTransfer, WeaTop, WeaSelect, WeaInputSearch, WeaHelpfulTip, WeaLocaleProvider } from 'ecCom';
import { Table, Button, Icon, message, Tooltip } from 'antd';
import isEqual from 'lodash/isEqual';
import has from 'lodash/has';
import * as mobx from 'mobx';
import toString from 'lodash/toString';
import FormulaSelection from './FormulaSelection';
const getLabel = WeaLocaleProvider.getLabel;
const WeaTransferList = WeaTransfer.list


export default class Formular extends React.Component {
    constructor(props) {
        super(props);
        const { formulaDesc = '', formula = '', formularLeftDatas = [] } = props;
        this.state = {
            computedIcon: ["+", "－", ">", "≥", "=", "（", "）", "%", "×", "÷", "<", "≤", "≠", "space", "←"],
            cursurIndex: 0, //光标
            formulaDesc: formulaDesc,
            formula: formula,
            areaSelectVal: '',//多行文本选中的文本值
            leftData: this.props.formularLeftDatas,
            tabletype: '',
            fieldNameInput: '',
            pointerLenArr: [], // [3,1,7,1]
            formulaArr: [], //['SUM','(','[MX.AB]',')']
            formulaDescArr: [], //['SUM','(','$-2222$',')']
            tempDetailTable: '',
            doDidUpdate: true,
            formulaInputName: ''
        }
        this.initFormulaArr(formulaDesc, formula);
    }

    shouldComponentUpdate(nextProps, nextState) {
        return !isEqual(this.state.cursurIndex, nextState.cursurIndex) ||
            this.state.formulaDesc !== nextState.formulaDesc ||
            this.state.formula !== nextState.formula ||
            this.state.tabletype !== nextState.tabletype ||
            this.state.fieldNameInput !== nextState.fieldNameInput ||
            this.state.formulaInputName !== nextState.formulaInputName ||
            this.props.detailTable !== nextProps.detailTable ||
            this.state.tempDetailTable !== nextState.tempDetailTable ||
            !isEqual(this.state.pointerLenArr, nextState.pointerLenArr) ||
            !isEqual(this.state.formulaArr, nextState.formulaArr) ||
            !isEqual(this.state.formulaDescArr, nextState.formulaDescArr);
    }

    //初始化
    initFormulaArr(formulaDesc, formula) {
        let { formulaDescArr, formulaArr, pointerLenArr } = this.state;
        if (formulaDesc) {
            const formulafun = formulaDesc.substr(0, formulaDesc.indexOf('（'));
            const formulaDescContent = formulaDesc.substr(formulaDesc.indexOf('（'));
            const formulaContent = formula.substr(formula.indexOf('（'));
            formulaDescArr.push(formulafun);
            formulaArr.push(formulafun);
            pointerLenArr.push(formulafun.length);
            this.splitFunContent(formulaDescContent, pointerLenArr, formulaDescArr);
            this.splitFunContent(formulaContent, [], formulaArr);

            this.setState({
                formulaDescArr, formulaArr, pointerLenArr, doDidUpdate: true
            });
        }
    }

    //解析公式内容
    splitFunContent(funContent, pointerLenArr, contentArr) {
        const fcLen = funContent.length;
        let len = 0;
        let itemContent = "";
        let flag = false;
        for (let i = 0; i < fcLen; i++) {
            len++;
            const c = funContent.charAt(i);
            if (!flag && /[\+\－\>\≥\=\（\）\×\÷\<\≤\≠\% \d\，\∈\∉\,]/.test(c)) {
                contentArr.push(c);
                pointerLenArr.push(len);
                len = 0;
                itemContent = '';
            } else if (c == "]") {
                itemContent += c;
                contentArr.push(itemContent);
                pointerLenArr.push(len);
                len = 0;
                itemContent = '';
                flag = false;
            } else if (c == '[') {
                flag = true;
                itemContent += c;
            } else {
                itemContent += c;
            }
        }
    }
    //value 字段值  type 0:btn 1:field 2:fun 
    setValue(value1, value2, type, fieldInfo) {
        let { cursurIndex, pointerLenArr, formulaArr, formulaDescArr } = this.state;
        let _cursurIndex = cursurIndex;
        //计算插入位置
        let insertPosition = this.getPointerPosition();
        insertPosition++;
        if (type == 0) {
            formulaDescArr.splice(insertPosition, 0, value1);
            formulaArr.splice(insertPosition, 0, value1);
            pointerLenArr.splice(insertPosition, 0, value1.length);
            _cursurIndex += 1;
        } else if (type == 1) {
            const { viewtype, tabletype } = fieldInfo;
            if (viewtype === 1) {
                let { detailTable = '' } = this.props;
                if (detailTable === '') {
                    detailTable = this.state.tempDetailTable;
                }
                if (detailTable === '') {
                    this.setState({ tempDetailTable: tabletype, doDidUpdate: true });
                } else {
                    if (tabletype !== detailTable) {
                        return;
                    }
                }
            }
            formulaDescArr.splice(insertPosition, 0, `[${value1}]`);
            formulaArr.splice(insertPosition, 0, `[${value2}]`);
            pointerLenArr.splice(insertPosition, 0, value1.length + 2);
            _cursurIndex += value1.length + 2;
        } else if (type == 2) {
            if (insertPosition == 1 && pointerLenArr.length > 0) {
                const startWith = formulaDescArr[0] === '（';
                formulaDescArr.splice(0, 0, value1);
                formulaArr.splice(0, 0, value1);
                pointerLenArr.splice(0, 0, value1.length);

                if (startWith) {
                    _cursurIndex += value1.length;
                } else {
                    formulaDescArr.splice(1, 0, "（");
                    formulaArr.splice(1, 0, "（");
                    pointerLenArr.splice(1, 0, 1);
                    _cursurIndex += value1.length + 1;
                }
            } else {
                const isIfFun = (value1 === 'SUMIF' || value1 === 'MAXIF' || value1 === 'MINIF');
                let prefix = 0;
                formulaDescArr.splice(insertPosition + prefix, 0, value1);
                formulaArr.splice(insertPosition + prefix, 0, value1);
                pointerLenArr.splice(insertPosition + prefix, 0, value1.length);
                prefix++;

                formulaDescArr.splice(insertPosition + prefix, 0, "（");
                formulaArr.splice(insertPosition + prefix, 0, "（");
                pointerLenArr.splice(insertPosition + prefix, 0, 1);
                prefix++;

                if (isIfFun) {
                    formulaDescArr.splice(insertPosition + prefix, 0, "，");
                    formulaArr.splice(insertPosition + prefix, 0, "，");
                    pointerLenArr.splice(insertPosition + prefix, 0, 1);
                    prefix++;
                }

                formulaDescArr.splice(insertPosition + prefix, 0, "）");
                formulaArr.splice(insertPosition + prefix, 0, "）");
                pointerLenArr.splice(insertPosition + prefix, 0, 1);
                _cursurIndex += value1.length + 1;
            }
        }
        this.setState({ pointerLenArr, formulaArr, formulaDescArr, cursurIndex: _cursurIndex, doDidUpdate: true });
    }

    getFormulaDesc() {
        const { formulaDescArr } = this.state;
        return formulaDescArr.join("");
    }

    getFormula() {
        const { formulaArr } = this.state;
        return formulaArr.join("");
    }

    deleteFormulContent() {
        let { pointerLenArr, formulaArr, formulaDescArr, cursurIndex } = this.state;
        if (cursurIndex == 0) return;
        if (formulaDescArr.length == 0) return;
        let _cursurIndex = cursurIndex;
        let delPosition = this.getPointerPosition();
        _cursurIndex = _cursurIndex - formulaDescArr[delPosition].length;
        pointerLenArr.splice(delPosition, 1);
        formulaArr.splice(delPosition, 1);
        formulaDescArr.splice(delPosition, 1);

        let { detailTable = '', formularLeftDatas } = this.props;
        let tempDetailTable = '';
        if (detailTable === '') {
            let ids = [];
            formulaArr.map(o => {
                if (/^\[(-{0,1}\d{1,})\]$/.test(o)) {
                    ids.push(RegExp.$1);
                }
            })
            if (ids.length > 0) {
                mobx.toJS(formularLeftDatas).map(o => {
                    const index = ids.indexOf(toString(o.id));
                    if (index > -1 && o.viewtype === 1) {
                        tempDetailTable = o.tabletype;
                    }
                })
            }
        }
        this.setState({ pointerLenArr, formulaArr, formulaDescArr, cursurIndex: _cursurIndex, tempDetailTable, doDidUpdate: true });
    }

    componentWillReceiveProps(nextProps) {
        if (this.state.formulaDesc == '' && nextProps.formulaDesc != '') {
            const { formulaDesc = '', formula = '' } = nextProps;
            this.setState({ formulaDesc: formulaDesc, formula: formula, doDidUpdate: true });
            this.initFormulaArr(formulaDesc, formula);
        }
    }

    getPointerPosition() {
        const { pointerLenArr, cursurIndex } = this.state;
        let len = 0;
        for (let i = 0; i < pointerLenArr.length; i++) {
            len += pointerLenArr[i];
            if (len >= cursurIndex) {
                return i;
            }
        }
        return 0;
    }

    componentDidUpdate() {
        const { doDidUpdate } = this.state;
        if (doDidUpdate) {
            this.setCaretPosition();
        }
    }

    componentWillUnmount() {
    }

    render() {
        let _this = this;
        const { countModalShow, formularSelects, formularRightDatas,browserFieldProps } = this.props;
        const { computedIcon, formulaDescArr, cursurIndex, leftData, tabletype = '', fieldNameInput = '', formulaInputName = '' } = this.state;
        let formulaDesc = formulaDescArr.join("");
        let _leftData = leftData;
        let _rightData = formularRightDatas;
        if ('' != tabletype) _leftData = leftData.filter((d) => d.tabletype == tabletype);
        if ('' != fieldNameInput) _leftData = leftData.filter((d) => d.label.indexOf(fieldNameInput) > -1);
        if ('' != formulaInputName) _rightData = formularRightDatas.filter((d) => d.fun.indexOf(formulaInputName) > -1);
        return (
            <div>
                {/* 公式 */}
                <WeaFormItem ecId={`${this && this.props && this.props.ecId || ''}_WeaFormItem@qdtk1f`}
                    label={getLabel(386271, "公式")}
                    labelCol={{ span: 24 }}
                    wrapperCol={{ span: 0 }}>
                </WeaFormItem>
                <WeaFormItem ecId={`${this && this.props && this.props.ecId || ''}_WeaFormItem@5dvt2f`}
                    label={getLabel(386271, "公式") + 'area'}
                    labelCol={{ span: 0 }}
                    wrapperCol={{ span: 24 }}>
                    <div className="formular-area">
                        <WeaTextarea ecId={`${this && this.props && this.props.ecId || ''}_WeaTextarea@cdy41f`}
                            fieldName="formulaContent"
                            value={formulaDesc}
                            ref={'formulaContent'}
                        />
                        {/* 计算符 */}
                        <div className="formular-count-icons">
                            {computedIcon.map(function (item, index) {
                                let className = item == 'space' ? 'formular-btn-space' : '';
                                return (
                                    <Button ecId={`${this && this.props && this.props.ecId || ''}_Button@gmueks@${index}`}
                                        type="ghost"
                                        title={item}
                                        size="small"
                                        className={className}
                                        onClick={_this.formularClick.bind(_this, index, item)}
                                    >
                                        {item}
                                    </Button>
                                )
                            })
                            }
                        </div>
                    </div>
                </WeaFormItem>
                {/* 双击选中流程数据和统计函数到公式框 */}
                <WeaFormItem ecId={`${this && this.props && this.props.ecId || ''}_WeaFormItem@t5levw`}
                    label={getLabel(386259, "双击选中流程数据和统计函数到公式框")}
                    labelCol={{ span: 24 }}
                    wrapperCol={{ span: 0 }}>
                </WeaFormItem>
                <WeaFormItem ecId={`${this && this.props && this.props.ecId || ''}_WeaFormItem@sv0jgu`}
                    label={getLabel(386273, "公式框")}
                    labelCol={{ span: 0 }}
                    wrapperCol={{ span: 24 }}>
                    <div className="formular-transfer-list" >
                        <div className="formular-transfer-formitem" >
                            <WeaTransferList ecId={`${this && this.props && this.props.ecId || ''}_WeaTransferList@kxbj4t`}
                                header={
                                    <div className="transferHeader">
                                        <span>{getLabel(386272, "流程数据")}</span>
                                        <div className="transferHeader-select">
                                            <WeaSelect ecId={`${this && this.props && this.props.ecId || ''}_WeaSelect@taak3n`}
                                                options={formularSelects}
                                                value={tabletype}
                                                onChange={(v) => this.setState({ tabletype: v, doDidUpdate: false })} />
                                            <WeaInputSearch ecId={`${this && this.props && this.props.ecId || ''}_WeaInputSearch@vx7kvl`}
                                                value={fieldNameInput}
                                                onSearch={(v) => { }}
                                                onSearchChange={(v) => this.setState({ fieldNameInput: v, doDidUpdate: false })} />
                                        </div>
                                    </div>
                                    // <WeaTop
                                    //     title={"流程数据"}
                                    //     buttons={[<WeaSelect
                                    //             options={formularSelects}
                                    //             value={""}
                                    //             onChange={(v)=> this.setState({tabletype:v,doDidUpdate:false})}/>,
                                    //         <WeaInputSearch 
                                    //             value={""} 
                                    //             onSearch={(v)=> {}}
                                    //             onSearchChange={(v)=> this.setState({fieldNameInput:v,doDidUpdate:false})}/>]}
                                    // >
                                    // </WeaTop>
                                }
                                data={_leftData}
                                renderItem={this.renderItem.bind(this)}
                                checkedCb={(keys) => { console.log(keys) }}
                                checkedKeys={[]}
                                onDoubleClick={(v, target) => {
                                    const { id, tabledesc, label, httype, type } = target;
                                    const formulaDescArr = this.state.formulaDescArr||[];
                                    if (formulaDescArr.length > 0 && this.state.formulaDescArr[0] == 'COUNTIF'
                                        && (has(browserFieldProps,`field${id}`))) {
                                        let conditionfield = {id,name:label};
                                        this.formulaSelection.showModal(true,conditionfield);
                                    } else {
                                        this.setValue(`${tabledesc}.${label}`, id, 1, target);
                                    }
                                }}
                            />
                        </div>
                        <div className="formular-transfer-formulars" >
                            <WeaTransferList ecId={`${this && this.props && this.props.ecId || ''}_WeaTransferList@bgecyp`}
                                header={
                                    <div className="transferHeader">
                                        <span>{getLabel(386260, "统计函数")}</span>
                                        <div className="transferHeader-no-select">
                                            <WeaInputSearch ecId={`${this && this.props && this.props.ecId || ''}_WeaInputSearch@uuxz6u`}
                                                value={formulaInputName}
                                                onSearch={(v) => { }}
                                                onSearchChange={(v) => this.setState({ formulaInputName: v, doDidUpdate: false })} />
                                        </div>
                                    </div>
                                    // <WeaTop
                                    //     title={"统计函数"}
                                    //     buttons={[
                                    //         <WeaInputSearch 
                                    //             value={""} 
                                    //             onSearch={(v)=> {}}
                                    //             onSearchChange={(v)=> {}}
                                    //         />]}
                                    // >
                                    // </WeaTop>
                                }
                                data={_rightData}
                                renderItem={this.renderFormulaItem}
                                checkedCb={(keys) => { console.log(keys) }}
                                checkedKeys={[]}
                                onDoubleClick={(v, target) => {
                                    this.setValue(target.fun, '', 2);
                                }}
                            />
                        </div>
                    </div>
                </WeaFormItem>
                <FormulaSelection ecId={`${this && this.props && this.props.ecId || ''}_FormulaSelection@9oca4x`} ref={(formulaSelection) => this.formulaSelection = formulaSelection} browserFieldProps = {browserFieldProps} formFields={leftData} onOk={(d) => this.countIfFormula(d)} />
            </div>
        )
    }
    //公式选择好之后执行事件
    countIfFormula(d = {}) {
        const {conditionValue = '',conditionfield = {},fieldInfo = {},operate = ''} = d;
        let operateTemp = '';
        switch (d.operate) {
            case '1': operateTemp = "="; break;
            case '2': operateTemp = "≠"; break;
            case '3': operateTemp = "∈"; break;
            case '4': operateTemp = "∉"; break;
            default: operateTemp = "";
        }
        if(operateTemp == "") {
            return "";
        }
        let value  = conditionValue;
        if(operateTemp == '∈' || operateTemp == '∉') {
            value = '（' + conditionValue + '）';
        }
        this.setValue(operateTemp + value, operateTemp + value,0);
        this.setValue(conditionfield.name, conditionfield.id, 1, fieldInfo);
    }
    //穿梭框的渲染方式
    renderItem(item) {
        let { detailTable = '' } = this.props;
        if (detailTable === '') {
            detailTable = this.state.tempDetailTable;
        }
        const disabelClassName = (item.viewtype === 1 && detailTable !== '' && item.tabletype !== detailTable) ? 'custom-report-disable-item' : '';
        return <div className={`custom-render-item ${disabelClassName}`}>
            <p>{item.label}</p>
            <p><span>{item.tabledesc}</span><span>{item.dbtype}</span></p>
        </div>
    }
    //穿梭框的渲染方式
    renderFormulaItem = (item) => {
        return <div className="custom-render-item">
            <p>
                <span style={{ 'color': '#666' }}>{item.fun}</span>
                <WeaHelpfulTip ecId={`${this && this.props && this.props.ecId || ''}_WeaHelpfulTip@4zdfc2`} title={item.description} />
            </p>
            <p>
                <span>{item.funDesc}</span>
            </p>
        </div>
    }
    componentDidMount() {
        let _this = this;
        jQuery(function () {
            //公式区域
            jQuery(document).delegate("#formulaContent", "click", function () {
                let index = _this.getCursorPosition();
                const { cursurIndex = 0 } = _this.state;
                if (index <= 0) index = 0;
                const { pointerLenArr = [] } = _this.state;
                let tempIndex = 0;

                for (let i = 0; i < pointerLenArr.length; i++) {
                    tempIndex += pointerLenArr[i];
                    if (tempIndex >= index) {
                        _this.setState({
                            cursurIndex: tempIndex, doDidUpdate: true
                        })

                        if (cursurIndex == tempIndex) {
                            _this.setCaretPosition();
                        }
                        break;
                    }
                }
            });

            jQuery("#formulaContent").keydown(function (e) {
                const keycode = e.keyCode;
                if (keycode === 8) {
                    _this.deleteFormulContent();
                } else if (keycode === 37) {
                    let { cursurIndex, pointerLenArr } = _this.state;
                    if (cursurIndex > 0) {
                        let p = _this.getPointerPosition();
                        _this.setState({ cursurIndex: cursurIndex - pointerLenArr[p], doDidUpdate: true });
                    }
                } else if (keycode === 39) {
                    let { cursurIndex, pointerLenArr } = _this.state;
                    let p = _this.getPointerPosition();
                    if (pointerLenArr.length > p + 1) {
                        let _cursurIndex = cursurIndex;
                        if (cursurIndex == 0) {
                            _cursurIndex += pointerLenArr[0];
                        } else {
                            _cursurIndex += pointerLenArr[p + 1];
                        }
                        _this.setState({ cursurIndex: _cursurIndex, doDidUpdate: true });
                    }
                } else {
                    //keycode === 188
                    if ((keycode >= 48 && keycode <= 57) || (keycode >= 96 && keycode <= 105)) {
                        const { key = '' } = e;
                        _this.setValue(key, key, 0);
                    }
                }
                return false;
            })
        });
    }

    formularClick(index, item) {
        if (index == 14) {
            this.deleteFormulContent();
        } else {
            if (item == 'space') {
                item = ' ';
            }
            this.setValue(item, '', 0);
        }
    }
    //获取当前鼠标指针在输入框文本中的位置
    getCursorPosition() {
        var oTxt1 = document.getElementById("formulaContent");
        var cursurPosition = 0;
        if (oTxt1.selectionStart) {//非IE浏览器
            cursurPosition = oTxt1.selectionStart;
        } else {//IE
            if (document.selection) {
                var range = document.selection.createRange();
                range.moveStart("character", -oTxt1.value.length);
                cursurPosition = range.text.length;
            }
        }
        return cursurPosition
    }
    //获取选中的文字
    getSelectText(editor) {
        if (!editor) return; editor.focus();
        if (editor.document && editor.document.selection)
            return editor.document.selection.createRange().text;
        else if ("selectionStart" in editor)
            return editor.value.substring(editor.selectionStart, editor.selectionEnd);
    }
    //获得焦点
    setCaretPosition() {
        let { formulaDescArr = [], cursurIndex = 0 } = this.state;
        const formulaDescLen = formulaDescArr.join("").length;
        const elm = $('#formulaContent')[0];
        if (cursurIndex < 0 || cursurIndex > formulaDescLen)	//定位到最后
            cursurIndex = formulaDescLen;
        if (elm.createTextRange) {	//IE
            let textRange = elm.createTextRange();
            textRange.moveStart('character', cursurIndex);
            textRange.collapse();
            textRange.select();
        } else if (elm.setSelectionRange) {
            elm.focus();
            elm.setSelectionRange(cursurIndex, cursurIndex);
        }
    }
    clearState() {
        this.setState({
            cursurIndex: 0,
            formulaDesc: '',
            formula: '',
            areaSelectVal: '',
            pointerLenArr: [],
            formulaArr: [],
            formulaDescArr: [],
            tabletype: '',
            tempDetailTable: '',
            doDidUpdate: true
        })
    }
}
